<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.9.1" />
<title>tronpytool.common.key API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>tronpytool.common.key</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">import hashlib
import random
from collections.abc import ByteString, Hashable
from typing import Any, Union

import base58
import ecdsa  # type: ignore
from Crypto.Hash import keccak

from tronpytool.exceptions import BadKey, BadSignature, BadAddress


def keccak256(data: bytes) -&gt; bytes:
    hasher = keccak.new(digest_bits=256)
    hasher.update(data)
    return hasher.digest()


def assure_bytes(value: Union[str, bytes]) -&gt; bytes:
    if isinstance(value, (str,)):
        return bytes.fromhex(value)
    if isinstance(value, (bytes,)):
        return value
    raise ValueError(&#34;bad bytes format&#34;)


def sha256(data: bytes) -&gt; bytes:
    hasher = hashlib.sha256()
    hasher.update(data)
    return hasher.digest()


def public_key_to_base58check_addr(pub_key: bytes) -&gt; str:
    primitive_addr = b&#34;\x41&#34; + keccak256(pub_key)[-20:]
    addr = base58.b58encode_check(primitive_addr)
    return addr.decode()


def public_key_to_addr(pub_key: bytes) -&gt; bytes:
    return b&#34;\x41&#34; + keccak256(pub_key)[-20:]


def to_base58check_address(raw_addr: Union[str, bytes]) -&gt; str:
    &#34;&#34;&#34;Convert hex address or base58check address to base58check address(and verify it).&#34;&#34;&#34;
    if isinstance(raw_addr, (str,)):
        if raw_addr[0] == &#34;T&#34; and len(raw_addr) == 34:
            try:
                # assert checked
                base58.b58decode_check(raw_addr)
            except ValueError:
                raise BadAddress(&#34;bad base58check format&#34;)
            return raw_addr
        elif len(raw_addr) == 42:
            if raw_addr.startswith(&#34;0x&#34;):  # eth address format
                return base58.b58encode_check(b&#34;\x41&#34; + bytes.fromhex(raw_addr[2:])).decode()
            else:
                return base58.b58encode_check(bytes.fromhex(raw_addr)).decode()
        elif raw_addr.startswith(&#34;0x&#34;) and len(raw_addr) == 44:
            return base58.b58encode_check(bytes.fromhex(raw_addr[2:])).decode()
    elif isinstance(raw_addr, (bytes, bytearray)):
        if len(raw_addr) == 21 and int(raw_addr[0]) == 0x41:
            return base58.b58encode_check(raw_addr).decode()
        if len(raw_addr) == 20:  # eth address format
            return base58.b58encode_check(b&#34;\x41&#34; + raw_addr).decode()
        return to_base58check_address(raw_addr.decode())
    raise BadAddress(repr(raw_addr))


def to_hex_address(raw_addr: Union[str, bytes]) -&gt; str:
    addr = to_base58check_address(raw_addr)
    return base58.b58decode_check(addr).hex()


def to_raw_address(raw_addr: Union[str, bytes]) -&gt; bytes:
    addr = to_base58check_address(raw_addr)
    return base58.b58decode_check(addr)


def to_tvm_address(raw_addr: Union[str, bytes]) -&gt; bytes:
    return to_raw_address(raw_addr)[1:]


def is_base58check_address(value: str) -&gt; bool:
    return value[0] == &#34;T&#34; and len(base58.b58decode_check(value)) == 21


def is_hex_address(value: str) -&gt; bool:
    return value.startswith(&#34;41&#34;) and len(bytes.fromhex(value)) == 21


def is_address(value: str) -&gt; bool:
    return is_base58check_address(value) or is_hex_address(value)


class BaseKey(ByteString, Hashable):
    _raw_key = None  # type: bytes

    # compatible with bytes.hex()
    def hex(self) -&gt; str:
        &#34;&#34;&#34;
        Key as a hex str.

        :returns: A hex str.
        &#34;&#34;&#34;
        return self._raw_key.hex()

    @classmethod
    def fromhex(cls, hex_str: str) -&gt; &#34;BaseKey&#34;:
        &#34;&#34;&#34;
        Construct a key from a hex str.

        :returns: The key object.
        &#34;&#34;&#34;
        return cls(bytes.fromhex(hex_str))

    def to_bytes(self) -&gt; bytes:
        return self._raw_key

    def __hash__(self) -&gt; int:
        return int.from_bytes(self._raw_key, &#34;big&#34;)

    def __str__(self) -&gt; str:
        return self.hex()

    def __int__(self) -&gt; int:
        return int.from_bytes(self._raw_key, &#34;big&#34;)

    def __len__(self) -&gt; int:
        return len(self._raw_key)

    # Must be typed with `ignore` due to
    # https://github.com/python/mypy/issues/1237
    def __getitem__(self, index: int) -&gt; int:  # type: ignore
        return self._raw_key[index]

    def __eq__(self, other: Any) -&gt; bool:
        if hasattr(other, &#34;to_bytes&#34;):
            return self.to_bytes() == other.to_bytes()
        elif isinstance(other, (bytes, bytearray)):
            return self.to_bytes() == other
        else:
            return False

    def __repr__(self) -&gt; str:
        return repr(self.hex())

    def __index__(self) -&gt; int:
        return self.__int__()

    def __hex__(self) -&gt; str:
        return self.hex()


class PublicKey(BaseKey):
    &#34;&#34;&#34;The public key.&#34;&#34;&#34;

    def __init__(self, public_key_bytes: bytes):
        try:
            assert isinstance(public_key_bytes, (bytes,))
            assert len(public_key_bytes) == 64
        except AssertionError:
            raise BadKey

        self._raw_key = public_key_bytes

        super().__init__()

    @classmethod
    def recover_from_msg(cls, message: bytes, signature: &#34;Signature&#34;):
        &#34;&#34;&#34;Recover public key(address) from raw message and signature.&#34;&#34;&#34;
        return signature.recover_public_key_from_msg(message)

    @classmethod
    def recover_from_msg_hash(cls, message_hash: bytes, signature: &#34;Signature&#34;):
        &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
        return signature.recover_public_key_from_msg_hash(message_hash)

    def verify_msg(self, message: bytes, signature: &#34;Signature&#34;) -&gt; bool:
        &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
        return signature.verify_msg(message, self)

    def verify_msg_hash(self, message_hash: bytes, signature: &#34;Signature&#34;) -&gt; bool:
        &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
        return signature.verify_msg_hash(message_hash, self)

    # Address conversions
    def to_base58check_address(self) -&gt; str:
        &#34;&#34;&#34;Get the base58check address of the public key.&#34;&#34;&#34;
        return public_key_to_base58check_addr(self._raw_key)

    def to_hex_address(self) -&gt; str:
        return public_key_to_addr(self._raw_key).hex()

    def to_address(self) -&gt; bytes:
        return public_key_to_addr(self._raw_key)

    def to_tvm_address(self) -&gt; bytes:
        return public_key_to_addr(self._raw_key)[1:]


class PrivateKey(BaseKey):
    &#34;&#34;&#34;The private key.&#34;&#34;&#34;

    _pubkey = None

    def __init__(self, private_key_bytes: bytes):
        try:
            assert isinstance(private_key_bytes, (bytes,))
            assert len(private_key_bytes) == 32
            assert (
                    0
                    &lt; int.from_bytes(private_key_bytes, &#34;big&#34;)
                    &lt; 115792089237316195423570985008687907852837564279074904382605163141518161494337
            )
        except AssertionError:
            raise BadKey

        self._raw_key = private_key_bytes

        priv_key = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1)
        self._pubkey = PublicKey(priv_key.get_verifying_key().to_string())

        super().__init__()

    @property
    def public_key(self) -&gt; &#34;PublicKey&#34;:
        return self._pubkey

    def sign_msg(self, message: bytes) -&gt; &#34;Signature&#34;:
        &#34;&#34;&#34;Sign a raw message.&#34;&#34;&#34;
        sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
        signature = sk.sign_deterministic(message)

        # recover address to get rec_id
        vks = ecdsa.VerifyingKey.from_public_key_recovery(
            signature, message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        for v, pk in enumerate(vks):
            if pk.to_string() == self._pubkey:
                break

        signature += bytes([v])
        return Signature(signature)

    def sign_msg_hash(self, message_hash: bytes) -&gt; &#34;Signature&#34;:
        &#34;&#34;&#34;Sign a message hash(sha256).&#34;&#34;&#34;
        sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
        signature = sk.sign_digest_deterministic(message_hash)

        # recover address to get rec_id
        vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
            signature, message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        for v, pk in enumerate(vks):
            if pk.to_string() == self._pubkey:
                break

        signature += bytes([v])
        return Signature(signature)

    @classmethod
    def random(cls) -&gt; &#34;PrivateKey&#34;:
        &#34;&#34;&#34;Generate a random private key.&#34;&#34;&#34;
        return cls(bytes([random.randint(0, 255) for _ in range(32)]))

    @classmethod
    def from_passphrase(cls, passphrase: bytes) -&gt; &#34;PrivateKey&#34;:
        &#34;&#34;&#34;Get a private key from sha256 of a passphrase.&#34;&#34;&#34;
        return cls(sha256(passphrase))


class Signature(ByteString):
    &#34;&#34;&#34;The signature object.&#34;&#34;&#34;

    _raw_signature = None

    def __init__(self, signature_bytes: bytes):
        try:
            assert isinstance(signature_bytes, (bytes,))
            assert len(signature_bytes) == 65
            assert signature_bytes[-1] in [0, 1]
        except AssertionError:
            raise BadSignature

        self._raw_signature = signature_bytes

        super().__init__()

    def recover_public_key_from_msg(self, message: bytes) -&gt; PublicKey:
        &#34;&#34;&#34;Recover public key(address) from message and signature.&#34;&#34;&#34;
        vks = ecdsa.VerifyingKey.from_public_key_recovery(
            self._raw_signature[:64], message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        return PublicKey(vks[self.v].to_string())

    def recover_public_key_from_msg_hash(self, message_hash: bytes) -&gt; PublicKey:
        &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
        vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
            self._raw_signature[:64], message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        return PublicKey(vks[self.v].to_string())

    def verify_msg(self, message: bytes, public_key: PublicKey) -&gt; bool:
        &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
        vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
        return vk.verify(self._raw_signature[:64], message, hashfunc=hashlib.sha256)

    def verify_msg_hash(self, message_hash: bytes, public_key: PublicKey) -&gt; bool:
        &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
        vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
        return vk.verify_digest(self._raw_signature[:64], message_hash)

    @property
    def v(self) -&gt; int:
        return self._raw_signature[64]

    def hex(self) -&gt; str:
        &#34;&#34;&#34;
        Return signature as a hex str.

        :returns: A hex str.
        &#34;&#34;&#34;
        return self._raw_signature.hex()

    @classmethod
    def fromhex(cls, hex_str: str) -&gt; &#39;Signature&#39;:
        &#34;&#34;&#34;Construct a Signature from hex str.&#34;&#34;&#34;
        return cls(bytes.fromhex(hex_str))

    def to_bytes(self) -&gt; bytes:
        return self._raw_signature

    def __hash__(self) -&gt; int:
        return int.from_bytes(self._raw_signature, &#34;big&#34;)

    def __str__(self) -&gt; str:
        return self.hex()

    def __int__(self) -&gt; int:
        return int.from_bytes(self._raw_signature, &#34;big&#34;)

    def __len__(self) -&gt; int:
        return 65

    def __getitem__(self, index: int) -&gt; int:  # type: ignore
        return self._raw_signature[index]

    def __eq__(self, other: Any) -&gt; bool:
        if hasattr(other, &#34;to_bytes&#34;):
            return self.to_bytes() == other.to_bytes()
        elif isinstance(other, (bytes, bytearray)):
            return self.to_bytes() == other
        else:
            return False

    def __repr__(self) -&gt; str:
        return repr(self.hex())

    def __index__(self) -&gt; int:
        return self.__int__()

    def __hex__(self) -&gt; str:
        return self.hex()</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="tronpytool.common.key.assure_bytes"><code class="name flex">
<span>def <span class="ident">assure_bytes</span></span>(<span>value: Union[str, bytes]) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def assure_bytes(value: Union[str, bytes]) -&gt; bytes:
    if isinstance(value, (str,)):
        return bytes.fromhex(value)
    if isinstance(value, (bytes,)):
        return value
    raise ValueError(&#34;bad bytes format&#34;)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.is_address"><code class="name flex">
<span>def <span class="ident">is_address</span></span>(<span>value: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def is_address(value: str) -&gt; bool:
    return is_base58check_address(value) or is_hex_address(value)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.is_base58check_address"><code class="name flex">
<span>def <span class="ident">is_base58check_address</span></span>(<span>value: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def is_base58check_address(value: str) -&gt; bool:
    return value[0] == &#34;T&#34; and len(base58.b58decode_check(value)) == 21</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.is_hex_address"><code class="name flex">
<span>def <span class="ident">is_hex_address</span></span>(<span>value: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def is_hex_address(value: str) -&gt; bool:
    return value.startswith(&#34;41&#34;) and len(bytes.fromhex(value)) == 21</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.keccak256"><code class="name flex">
<span>def <span class="ident">keccak256</span></span>(<span>data: bytes) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def keccak256(data: bytes) -&gt; bytes:
    hasher = keccak.new(digest_bits=256)
    hasher.update(data)
    return hasher.digest()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.public_key_to_addr"><code class="name flex">
<span>def <span class="ident">public_key_to_addr</span></span>(<span>pub_key: bytes) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def public_key_to_addr(pub_key: bytes) -&gt; bytes:
    return b&#34;\x41&#34; + keccak256(pub_key)[-20:]</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.public_key_to_base58check_addr"><code class="name flex">
<span>def <span class="ident">public_key_to_base58check_addr</span></span>(<span>pub_key: bytes) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def public_key_to_base58check_addr(pub_key: bytes) -&gt; str:
    primitive_addr = b&#34;\x41&#34; + keccak256(pub_key)[-20:]
    addr = base58.b58encode_check(primitive_addr)
    return addr.decode()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.sha256"><code class="name flex">
<span>def <span class="ident">sha256</span></span>(<span>data: bytes) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def sha256(data: bytes) -&gt; bytes:
    hasher = hashlib.sha256()
    hasher.update(data)
    return hasher.digest()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.to_base58check_address"><code class="name flex">
<span>def <span class="ident">to_base58check_address</span></span>(<span>raw_addr: Union[str, bytes]) ‑> str</span>
</code></dt>
<dd>
<div class="desc"><p>Convert hex address or base58check address to base58check address(and verify it).</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_base58check_address(raw_addr: Union[str, bytes]) -&gt; str:
    &#34;&#34;&#34;Convert hex address or base58check address to base58check address(and verify it).&#34;&#34;&#34;
    if isinstance(raw_addr, (str,)):
        if raw_addr[0] == &#34;T&#34; and len(raw_addr) == 34:
            try:
                # assert checked
                base58.b58decode_check(raw_addr)
            except ValueError:
                raise BadAddress(&#34;bad base58check format&#34;)
            return raw_addr
        elif len(raw_addr) == 42:
            if raw_addr.startswith(&#34;0x&#34;):  # eth address format
                return base58.b58encode_check(b&#34;\x41&#34; + bytes.fromhex(raw_addr[2:])).decode()
            else:
                return base58.b58encode_check(bytes.fromhex(raw_addr)).decode()
        elif raw_addr.startswith(&#34;0x&#34;) and len(raw_addr) == 44:
            return base58.b58encode_check(bytes.fromhex(raw_addr[2:])).decode()
    elif isinstance(raw_addr, (bytes, bytearray)):
        if len(raw_addr) == 21 and int(raw_addr[0]) == 0x41:
            return base58.b58encode_check(raw_addr).decode()
        if len(raw_addr) == 20:  # eth address format
            return base58.b58encode_check(b&#34;\x41&#34; + raw_addr).decode()
        return to_base58check_address(raw_addr.decode())
    raise BadAddress(repr(raw_addr))</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.to_hex_address"><code class="name flex">
<span>def <span class="ident">to_hex_address</span></span>(<span>raw_addr: Union[str, bytes]) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_hex_address(raw_addr: Union[str, bytes]) -&gt; str:
    addr = to_base58check_address(raw_addr)
    return base58.b58decode_check(addr).hex()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.to_raw_address"><code class="name flex">
<span>def <span class="ident">to_raw_address</span></span>(<span>raw_addr: Union[str, bytes]) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_raw_address(raw_addr: Union[str, bytes]) -&gt; bytes:
    addr = to_base58check_address(raw_addr)
    return base58.b58decode_check(addr)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.to_tvm_address"><code class="name flex">
<span>def <span class="ident">to_tvm_address</span></span>(<span>raw_addr: Union[str, bytes]) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_tvm_address(raw_addr: Union[str, bytes]) -&gt; bytes:
    return to_raw_address(raw_addr)[1:]</code></pre>
</details>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="tronpytool.common.key.BaseKey"><code class="flex name class">
<span>class <span class="ident">BaseKey</span></span>
</code></dt>
<dd>
<div class="desc"><p>This unifies bytes and bytearray.</p>
<p>XXX Should add all their methods.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class BaseKey(ByteString, Hashable):
    _raw_key = None  # type: bytes

    # compatible with bytes.hex()
    def hex(self) -&gt; str:
        &#34;&#34;&#34;
        Key as a hex str.

        :returns: A hex str.
        &#34;&#34;&#34;
        return self._raw_key.hex()

    @classmethod
    def fromhex(cls, hex_str: str) -&gt; &#34;BaseKey&#34;:
        &#34;&#34;&#34;
        Construct a key from a hex str.

        :returns: The key object.
        &#34;&#34;&#34;
        return cls(bytes.fromhex(hex_str))

    def to_bytes(self) -&gt; bytes:
        return self._raw_key

    def __hash__(self) -&gt; int:
        return int.from_bytes(self._raw_key, &#34;big&#34;)

    def __str__(self) -&gt; str:
        return self.hex()

    def __int__(self) -&gt; int:
        return int.from_bytes(self._raw_key, &#34;big&#34;)

    def __len__(self) -&gt; int:
        return len(self._raw_key)

    # Must be typed with `ignore` due to
    # https://github.com/python/mypy/issues/1237
    def __getitem__(self, index: int) -&gt; int:  # type: ignore
        return self._raw_key[index]

    def __eq__(self, other: Any) -&gt; bool:
        if hasattr(other, &#34;to_bytes&#34;):
            return self.to_bytes() == other.to_bytes()
        elif isinstance(other, (bytes, bytearray)):
            return self.to_bytes() == other
        else:
            return False

    def __repr__(self) -&gt; str:
        return repr(self.hex())

    def __index__(self) -&gt; int:
        return self.__int__()

    def __hex__(self) -&gt; str:
        return self.hex()</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>collections.abc.ByteString</li>
<li>collections.abc.Sequence</li>
<li>collections.abc.Reversible</li>
<li>collections.abc.Collection</li>
<li>collections.abc.Sized</li>
<li>collections.abc.Iterable</li>
<li>collections.abc.Container</li>
<li>collections.abc.Hashable</li>
</ul>
<h3>Subclasses</h3>
<ul class="hlist">
<li><a title="tronpytool.common.key.PrivateKey" href="#tronpytool.common.key.PrivateKey">PrivateKey</a></li>
<li><a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a></li>
</ul>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.common.key.BaseKey.fromhex"><code class="name flex">
<span>def <span class="ident">fromhex</span></span>(<span>hex_str: str) ‑> <a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Construct a key from a hex str.</p>
<p>:returns: The key object.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def fromhex(cls, hex_str: str) -&gt; &#34;BaseKey&#34;:
    &#34;&#34;&#34;
    Construct a key from a hex str.

    :returns: The key object.
    &#34;&#34;&#34;
    return cls(bytes.fromhex(hex_str))</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.common.key.BaseKey.hex"><code class="name flex">
<span>def <span class="ident">hex</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"><p>Key as a hex str.</p>
<p>:returns: A hex str.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def hex(self) -&gt; str:
    &#34;&#34;&#34;
    Key as a hex str.

    :returns: A hex str.
    &#34;&#34;&#34;
    return self._raw_key.hex()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.BaseKey.to_bytes"><code class="name flex">
<span>def <span class="ident">to_bytes</span></span>(<span>self) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_bytes(self) -&gt; bytes:
    return self._raw_key</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="tronpytool.common.key.PrivateKey"><code class="flex name class">
<span>class <span class="ident">PrivateKey</span></span>
<span>(</span><span>private_key_bytes: bytes)</span>
</code></dt>
<dd>
<div class="desc"><p>The private key.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PrivateKey(BaseKey):
    &#34;&#34;&#34;The private key.&#34;&#34;&#34;

    _pubkey = None

    def __init__(self, private_key_bytes: bytes):
        try:
            assert isinstance(private_key_bytes, (bytes,))
            assert len(private_key_bytes) == 32
            assert (
                    0
                    &lt; int.from_bytes(private_key_bytes, &#34;big&#34;)
                    &lt; 115792089237316195423570985008687907852837564279074904382605163141518161494337
            )
        except AssertionError:
            raise BadKey

        self._raw_key = private_key_bytes

        priv_key = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1)
        self._pubkey = PublicKey(priv_key.get_verifying_key().to_string())

        super().__init__()

    @property
    def public_key(self) -&gt; &#34;PublicKey&#34;:
        return self._pubkey

    def sign_msg(self, message: bytes) -&gt; &#34;Signature&#34;:
        &#34;&#34;&#34;Sign a raw message.&#34;&#34;&#34;
        sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
        signature = sk.sign_deterministic(message)

        # recover address to get rec_id
        vks = ecdsa.VerifyingKey.from_public_key_recovery(
            signature, message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        for v, pk in enumerate(vks):
            if pk.to_string() == self._pubkey:
                break

        signature += bytes([v])
        return Signature(signature)

    def sign_msg_hash(self, message_hash: bytes) -&gt; &#34;Signature&#34;:
        &#34;&#34;&#34;Sign a message hash(sha256).&#34;&#34;&#34;
        sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
        signature = sk.sign_digest_deterministic(message_hash)

        # recover address to get rec_id
        vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
            signature, message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        for v, pk in enumerate(vks):
            if pk.to_string() == self._pubkey:
                break

        signature += bytes([v])
        return Signature(signature)

    @classmethod
    def random(cls) -&gt; &#34;PrivateKey&#34;:
        &#34;&#34;&#34;Generate a random private key.&#34;&#34;&#34;
        return cls(bytes([random.randint(0, 255) for _ in range(32)]))

    @classmethod
    def from_passphrase(cls, passphrase: bytes) -&gt; &#34;PrivateKey&#34;:
        &#34;&#34;&#34;Get a private key from sha256 of a passphrase.&#34;&#34;&#34;
        return cls(sha256(passphrase))</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></li>
<li>collections.abc.ByteString</li>
<li>collections.abc.Sequence</li>
<li>collections.abc.Reversible</li>
<li>collections.abc.Collection</li>
<li>collections.abc.Sized</li>
<li>collections.abc.Iterable</li>
<li>collections.abc.Container</li>
<li>collections.abc.Hashable</li>
</ul>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.common.key.PrivateKey.from_passphrase"><code class="name flex">
<span>def <span class="ident">from_passphrase</span></span>(<span>passphrase: bytes) ‑> <a title="tronpytool.common.key.PrivateKey" href="#tronpytool.common.key.PrivateKey">PrivateKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Get a private key from sha256 of a passphrase.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def from_passphrase(cls, passphrase: bytes) -&gt; &#34;PrivateKey&#34;:
    &#34;&#34;&#34;Get a private key from sha256 of a passphrase.&#34;&#34;&#34;
    return cls(sha256(passphrase))</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PrivateKey.random"><code class="name flex">
<span>def <span class="ident">random</span></span>(<span>) ‑> <a title="tronpytool.common.key.PrivateKey" href="#tronpytool.common.key.PrivateKey">PrivateKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Generate a random private key.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def random(cls) -&gt; &#34;PrivateKey&#34;:
    &#34;&#34;&#34;Generate a random private key.&#34;&#34;&#34;
    return cls(bytes([random.randint(0, 255) for _ in range(32)]))</code></pre>
</details>
</dd>
</dl>
<h3>Instance variables</h3>
<dl>
<dt id="tronpytool.common.key.PrivateKey.public_key"><code class="name">var <span class="ident">public_key</span> : <a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a></code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def public_key(self) -&gt; &#34;PublicKey&#34;:
    return self._pubkey</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.common.key.PrivateKey.sign_msg"><code class="name flex">
<span>def <span class="ident">sign_msg</span></span>(<span>self, message: bytes) ‑> <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a></span>
</code></dt>
<dd>
<div class="desc"><p>Sign a raw message.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def sign_msg(self, message: bytes) -&gt; &#34;Signature&#34;:
    &#34;&#34;&#34;Sign a raw message.&#34;&#34;&#34;
    sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
    signature = sk.sign_deterministic(message)

    # recover address to get rec_id
    vks = ecdsa.VerifyingKey.from_public_key_recovery(
        signature, message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
    )
    for v, pk in enumerate(vks):
        if pk.to_string() == self._pubkey:
            break

    signature += bytes([v])
    return Signature(signature)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PrivateKey.sign_msg_hash"><code class="name flex">
<span>def <span class="ident">sign_msg_hash</span></span>(<span>self, message_hash: bytes) ‑> <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a></span>
</code></dt>
<dd>
<div class="desc"><p>Sign a message hash(sha256).</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def sign_msg_hash(self, message_hash: bytes) -&gt; &#34;Signature&#34;:
    &#34;&#34;&#34;Sign a message hash(sha256).&#34;&#34;&#34;
    sk = ecdsa.SigningKey.from_string(self._raw_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
    signature = sk.sign_digest_deterministic(message_hash)

    # recover address to get rec_id
    vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
        signature, message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
    )
    for v, pk in enumerate(vks):
        if pk.to_string() == self._pubkey:
            break

    signature += bytes([v])
    return Signature(signature)</code></pre>
</details>
</dd>
</dl>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></b></code>:
<ul class="hlist">
<li><code><a title="tronpytool.common.key.BaseKey.fromhex" href="#tronpytool.common.key.BaseKey.fromhex">fromhex</a></code></li>
<li><code><a title="tronpytool.common.key.BaseKey.hex" href="#tronpytool.common.key.BaseKey.hex">hex</a></code></li>
</ul>
</li>
</ul>
</dd>
<dt id="tronpytool.common.key.PublicKey"><code class="flex name class">
<span>class <span class="ident">PublicKey</span></span>
<span>(</span><span>public_key_bytes: bytes)</span>
</code></dt>
<dd>
<div class="desc"><p>The public key.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PublicKey(BaseKey):
    &#34;&#34;&#34;The public key.&#34;&#34;&#34;

    def __init__(self, public_key_bytes: bytes):
        try:
            assert isinstance(public_key_bytes, (bytes,))
            assert len(public_key_bytes) == 64
        except AssertionError:
            raise BadKey

        self._raw_key = public_key_bytes

        super().__init__()

    @classmethod
    def recover_from_msg(cls, message: bytes, signature: &#34;Signature&#34;):
        &#34;&#34;&#34;Recover public key(address) from raw message and signature.&#34;&#34;&#34;
        return signature.recover_public_key_from_msg(message)

    @classmethod
    def recover_from_msg_hash(cls, message_hash: bytes, signature: &#34;Signature&#34;):
        &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
        return signature.recover_public_key_from_msg_hash(message_hash)

    def verify_msg(self, message: bytes, signature: &#34;Signature&#34;) -&gt; bool:
        &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
        return signature.verify_msg(message, self)

    def verify_msg_hash(self, message_hash: bytes, signature: &#34;Signature&#34;) -&gt; bool:
        &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
        return signature.verify_msg_hash(message_hash, self)

    # Address conversions
    def to_base58check_address(self) -&gt; str:
        &#34;&#34;&#34;Get the base58check address of the public key.&#34;&#34;&#34;
        return public_key_to_base58check_addr(self._raw_key)

    def to_hex_address(self) -&gt; str:
        return public_key_to_addr(self._raw_key).hex()

    def to_address(self) -&gt; bytes:
        return public_key_to_addr(self._raw_key)

    def to_tvm_address(self) -&gt; bytes:
        return public_key_to_addr(self._raw_key)[1:]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></li>
<li>collections.abc.ByteString</li>
<li>collections.abc.Sequence</li>
<li>collections.abc.Reversible</li>
<li>collections.abc.Collection</li>
<li>collections.abc.Sized</li>
<li>collections.abc.Iterable</li>
<li>collections.abc.Container</li>
<li>collections.abc.Hashable</li>
</ul>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.common.key.PublicKey.recover_from_msg"><code class="name flex">
<span>def <span class="ident">recover_from_msg</span></span>(<span>message: bytes, signature: <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a>)</span>
</code></dt>
<dd>
<div class="desc"><p>Recover public key(address) from raw message and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def recover_from_msg(cls, message: bytes, signature: &#34;Signature&#34;):
    &#34;&#34;&#34;Recover public key(address) from raw message and signature.&#34;&#34;&#34;
    return signature.recover_public_key_from_msg(message)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.recover_from_msg_hash"><code class="name flex">
<span>def <span class="ident">recover_from_msg_hash</span></span>(<span>message_hash: bytes, signature: <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a>)</span>
</code></dt>
<dd>
<div class="desc"><p>Recover public key(address) from message hash and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def recover_from_msg_hash(cls, message_hash: bytes, signature: &#34;Signature&#34;):
    &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
    return signature.recover_public_key_from_msg_hash(message_hash)</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.common.key.PublicKey.to_address"><code class="name flex">
<span>def <span class="ident">to_address</span></span>(<span>self) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_address(self) -&gt; bytes:
    return public_key_to_addr(self._raw_key)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.to_base58check_address"><code class="name flex">
<span>def <span class="ident">to_base58check_address</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"><p>Get the base58check address of the public key.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_base58check_address(self) -&gt; str:
    &#34;&#34;&#34;Get the base58check address of the public key.&#34;&#34;&#34;
    return public_key_to_base58check_addr(self._raw_key)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.to_hex_address"><code class="name flex">
<span>def <span class="ident">to_hex_address</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_hex_address(self) -&gt; str:
    return public_key_to_addr(self._raw_key).hex()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.to_tvm_address"><code class="name flex">
<span>def <span class="ident">to_tvm_address</span></span>(<span>self) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_tvm_address(self) -&gt; bytes:
    return public_key_to_addr(self._raw_key)[1:]</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.verify_msg"><code class="name flex">
<span>def <span class="ident">verify_msg</span></span>(<span>self, message: bytes, signature: <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a>) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Verify message and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def verify_msg(self, message: bytes, signature: &#34;Signature&#34;) -&gt; bool:
    &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
    return signature.verify_msg(message, self)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.PublicKey.verify_msg_hash"><code class="name flex">
<span>def <span class="ident">verify_msg_hash</span></span>(<span>self, message_hash: bytes, signature: <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a>) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Verify message hash and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def verify_msg_hash(self, message_hash: bytes, signature: &#34;Signature&#34;) -&gt; bool:
    &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
    return signature.verify_msg_hash(message_hash, self)</code></pre>
</details>
</dd>
</dl>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></b></code>:
<ul class="hlist">
<li><code><a title="tronpytool.common.key.BaseKey.fromhex" href="#tronpytool.common.key.BaseKey.fromhex">fromhex</a></code></li>
<li><code><a title="tronpytool.common.key.BaseKey.hex" href="#tronpytool.common.key.BaseKey.hex">hex</a></code></li>
</ul>
</li>
</ul>
</dd>
<dt id="tronpytool.common.key.Signature"><code class="flex name class">
<span>class <span class="ident">Signature</span></span>
<span>(</span><span>signature_bytes: bytes)</span>
</code></dt>
<dd>
<div class="desc"><p>The signature object.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class Signature(ByteString):
    &#34;&#34;&#34;The signature object.&#34;&#34;&#34;

    _raw_signature = None

    def __init__(self, signature_bytes: bytes):
        try:
            assert isinstance(signature_bytes, (bytes,))
            assert len(signature_bytes) == 65
            assert signature_bytes[-1] in [0, 1]
        except AssertionError:
            raise BadSignature

        self._raw_signature = signature_bytes

        super().__init__()

    def recover_public_key_from_msg(self, message: bytes) -&gt; PublicKey:
        &#34;&#34;&#34;Recover public key(address) from message and signature.&#34;&#34;&#34;
        vks = ecdsa.VerifyingKey.from_public_key_recovery(
            self._raw_signature[:64], message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        return PublicKey(vks[self.v].to_string())

    def recover_public_key_from_msg_hash(self, message_hash: bytes) -&gt; PublicKey:
        &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
        vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
            self._raw_signature[:64], message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
        )
        return PublicKey(vks[self.v].to_string())

    def verify_msg(self, message: bytes, public_key: PublicKey) -&gt; bool:
        &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
        vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
        return vk.verify(self._raw_signature[:64], message, hashfunc=hashlib.sha256)

    def verify_msg_hash(self, message_hash: bytes, public_key: PublicKey) -&gt; bool:
        &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
        vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
        return vk.verify_digest(self._raw_signature[:64], message_hash)

    @property
    def v(self) -&gt; int:
        return self._raw_signature[64]

    def hex(self) -&gt; str:
        &#34;&#34;&#34;
        Return signature as a hex str.

        :returns: A hex str.
        &#34;&#34;&#34;
        return self._raw_signature.hex()

    @classmethod
    def fromhex(cls, hex_str: str) -&gt; &#39;Signature&#39;:
        &#34;&#34;&#34;Construct a Signature from hex str.&#34;&#34;&#34;
        return cls(bytes.fromhex(hex_str))

    def to_bytes(self) -&gt; bytes:
        return self._raw_signature

    def __hash__(self) -&gt; int:
        return int.from_bytes(self._raw_signature, &#34;big&#34;)

    def __str__(self) -&gt; str:
        return self.hex()

    def __int__(self) -&gt; int:
        return int.from_bytes(self._raw_signature, &#34;big&#34;)

    def __len__(self) -&gt; int:
        return 65

    def __getitem__(self, index: int) -&gt; int:  # type: ignore
        return self._raw_signature[index]

    def __eq__(self, other: Any) -&gt; bool:
        if hasattr(other, &#34;to_bytes&#34;):
            return self.to_bytes() == other.to_bytes()
        elif isinstance(other, (bytes, bytearray)):
            return self.to_bytes() == other
        else:
            return False

    def __repr__(self) -&gt; str:
        return repr(self.hex())

    def __index__(self) -&gt; int:
        return self.__int__()

    def __hex__(self) -&gt; str:
        return self.hex()</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>collections.abc.ByteString</li>
<li>collections.abc.Sequence</li>
<li>collections.abc.Reversible</li>
<li>collections.abc.Collection</li>
<li>collections.abc.Sized</li>
<li>collections.abc.Iterable</li>
<li>collections.abc.Container</li>
</ul>
<h3>Static methods</h3>
<dl>
<dt id="tronpytool.common.key.Signature.fromhex"><code class="name flex">
<span>def <span class="ident">fromhex</span></span>(<span>hex_str: str) ‑> <a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a></span>
</code></dt>
<dd>
<div class="desc"><p>Construct a Signature from hex str.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def fromhex(cls, hex_str: str) -&gt; &#39;Signature&#39;:
    &#34;&#34;&#34;Construct a Signature from hex str.&#34;&#34;&#34;
    return cls(bytes.fromhex(hex_str))</code></pre>
</details>
</dd>
</dl>
<h3>Instance variables</h3>
<dl>
<dt id="tronpytool.common.key.Signature.v"><code class="name">var <span class="ident">v</span> : int</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@property
def v(self) -&gt; int:
    return self._raw_signature[64]</code></pre>
</details>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="tronpytool.common.key.Signature.hex"><code class="name flex">
<span>def <span class="ident">hex</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"><p>Return signature as a hex str.</p>
<p>:returns: A hex str.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def hex(self) -&gt; str:
    &#34;&#34;&#34;
    Return signature as a hex str.

    :returns: A hex str.
    &#34;&#34;&#34;
    return self._raw_signature.hex()</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.Signature.recover_public_key_from_msg"><code class="name flex">
<span>def <span class="ident">recover_public_key_from_msg</span></span>(<span>self, message: bytes) ‑> <a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Recover public key(address) from message and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def recover_public_key_from_msg(self, message: bytes) -&gt; PublicKey:
    &#34;&#34;&#34;Recover public key(address) from message and signature.&#34;&#34;&#34;
    vks = ecdsa.VerifyingKey.from_public_key_recovery(
        self._raw_signature[:64], message, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
    )
    return PublicKey(vks[self.v].to_string())</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.Signature.recover_public_key_from_msg_hash"><code class="name flex">
<span>def <span class="ident">recover_public_key_from_msg_hash</span></span>(<span>self, message_hash: bytes) ‑> <a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a></span>
</code></dt>
<dd>
<div class="desc"><p>Recover public key(address) from message hash and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def recover_public_key_from_msg_hash(self, message_hash: bytes) -&gt; PublicKey:
    &#34;&#34;&#34;Recover public key(address) from message hash and signature.&#34;&#34;&#34;
    vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
        self._raw_signature[:64], message_hash, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256
    )
    return PublicKey(vks[self.v].to_string())</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.Signature.to_bytes"><code class="name flex">
<span>def <span class="ident">to_bytes</span></span>(<span>self) ‑> bytes</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def to_bytes(self) -&gt; bytes:
    return self._raw_signature</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.Signature.verify_msg"><code class="name flex">
<span>def <span class="ident">verify_msg</span></span>(<span>self, message: bytes, public_key: <a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a>) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Verify message and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def verify_msg(self, message: bytes, public_key: PublicKey) -&gt; bool:
    &#34;&#34;&#34;Verify message and signature.&#34;&#34;&#34;
    vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
    return vk.verify(self._raw_signature[:64], message, hashfunc=hashlib.sha256)</code></pre>
</details>
</dd>
<dt id="tronpytool.common.key.Signature.verify_msg_hash"><code class="name flex">
<span>def <span class="ident">verify_msg_hash</span></span>(<span>self, message_hash: bytes, public_key: <a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a>) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Verify message hash and signature.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def verify_msg_hash(self, message_hash: bytes, public_key: PublicKey) -&gt; bool:
    &#34;&#34;&#34;Verify message hash and signature.&#34;&#34;&#34;
    vk = ecdsa.VerifyingKey.from_string(public_key.to_bytes(), curve=ecdsa.SECP256k1)
    return vk.verify_digest(self._raw_signature[:64], message_hash)</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="tronpytool.common" href="index.html">tronpytool.common</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="tronpytool.common.key.assure_bytes" href="#tronpytool.common.key.assure_bytes">assure_bytes</a></code></li>
<li><code><a title="tronpytool.common.key.is_address" href="#tronpytool.common.key.is_address">is_address</a></code></li>
<li><code><a title="tronpytool.common.key.is_base58check_address" href="#tronpytool.common.key.is_base58check_address">is_base58check_address</a></code></li>
<li><code><a title="tronpytool.common.key.is_hex_address" href="#tronpytool.common.key.is_hex_address">is_hex_address</a></code></li>
<li><code><a title="tronpytool.common.key.keccak256" href="#tronpytool.common.key.keccak256">keccak256</a></code></li>
<li><code><a title="tronpytool.common.key.public_key_to_addr" href="#tronpytool.common.key.public_key_to_addr">public_key_to_addr</a></code></li>
<li><code><a title="tronpytool.common.key.public_key_to_base58check_addr" href="#tronpytool.common.key.public_key_to_base58check_addr">public_key_to_base58check_addr</a></code></li>
<li><code><a title="tronpytool.common.key.sha256" href="#tronpytool.common.key.sha256">sha256</a></code></li>
<li><code><a title="tronpytool.common.key.to_base58check_address" href="#tronpytool.common.key.to_base58check_address">to_base58check_address</a></code></li>
<li><code><a title="tronpytool.common.key.to_hex_address" href="#tronpytool.common.key.to_hex_address">to_hex_address</a></code></li>
<li><code><a title="tronpytool.common.key.to_raw_address" href="#tronpytool.common.key.to_raw_address">to_raw_address</a></code></li>
<li><code><a title="tronpytool.common.key.to_tvm_address" href="#tronpytool.common.key.to_tvm_address">to_tvm_address</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="tronpytool.common.key.BaseKey" href="#tronpytool.common.key.BaseKey">BaseKey</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.common.key.BaseKey.fromhex" href="#tronpytool.common.key.BaseKey.fromhex">fromhex</a></code></li>
<li><code><a title="tronpytool.common.key.BaseKey.hex" href="#tronpytool.common.key.BaseKey.hex">hex</a></code></li>
<li><code><a title="tronpytool.common.key.BaseKey.to_bytes" href="#tronpytool.common.key.BaseKey.to_bytes">to_bytes</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="tronpytool.common.key.PrivateKey" href="#tronpytool.common.key.PrivateKey">PrivateKey</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.common.key.PrivateKey.from_passphrase" href="#tronpytool.common.key.PrivateKey.from_passphrase">from_passphrase</a></code></li>
<li><code><a title="tronpytool.common.key.PrivateKey.public_key" href="#tronpytool.common.key.PrivateKey.public_key">public_key</a></code></li>
<li><code><a title="tronpytool.common.key.PrivateKey.random" href="#tronpytool.common.key.PrivateKey.random">random</a></code></li>
<li><code><a title="tronpytool.common.key.PrivateKey.sign_msg" href="#tronpytool.common.key.PrivateKey.sign_msg">sign_msg</a></code></li>
<li><code><a title="tronpytool.common.key.PrivateKey.sign_msg_hash" href="#tronpytool.common.key.PrivateKey.sign_msg_hash">sign_msg_hash</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="tronpytool.common.key.PublicKey" href="#tronpytool.common.key.PublicKey">PublicKey</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.common.key.PublicKey.recover_from_msg" href="#tronpytool.common.key.PublicKey.recover_from_msg">recover_from_msg</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.recover_from_msg_hash" href="#tronpytool.common.key.PublicKey.recover_from_msg_hash">recover_from_msg_hash</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.to_address" href="#tronpytool.common.key.PublicKey.to_address">to_address</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.to_base58check_address" href="#tronpytool.common.key.PublicKey.to_base58check_address">to_base58check_address</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.to_hex_address" href="#tronpytool.common.key.PublicKey.to_hex_address">to_hex_address</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.to_tvm_address" href="#tronpytool.common.key.PublicKey.to_tvm_address">to_tvm_address</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.verify_msg" href="#tronpytool.common.key.PublicKey.verify_msg">verify_msg</a></code></li>
<li><code><a title="tronpytool.common.key.PublicKey.verify_msg_hash" href="#tronpytool.common.key.PublicKey.verify_msg_hash">verify_msg_hash</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="tronpytool.common.key.Signature" href="#tronpytool.common.key.Signature">Signature</a></code></h4>
<ul class="">
<li><code><a title="tronpytool.common.key.Signature.fromhex" href="#tronpytool.common.key.Signature.fromhex">fromhex</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.hex" href="#tronpytool.common.key.Signature.hex">hex</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.recover_public_key_from_msg" href="#tronpytool.common.key.Signature.recover_public_key_from_msg">recover_public_key_from_msg</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.recover_public_key_from_msg_hash" href="#tronpytool.common.key.Signature.recover_public_key_from_msg_hash">recover_public_key_from_msg_hash</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.to_bytes" href="#tronpytool.common.key.Signature.to_bytes">to_bytes</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.v" href="#tronpytool.common.key.Signature.v">v</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.verify_msg" href="#tronpytool.common.key.Signature.verify_msg">verify_msg</a></code></li>
<li><code><a title="tronpytool.common.key.Signature.verify_msg_hash" href="#tronpytool.common.key.Signature.verify_msg_hash">verify_msg_hash</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.1</a>.</p>
</footer>
</body>
</html>